package com.zdya.combatdocuments.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zdya.combatdocuments.component.CombatDocumentConfig;
import com.zdya.combatdocuments.entity.*;
import com.zdya.combatdocuments.entity.vo.*;
import com.zdya.combatdocuments.ethereum.EthChain;
import com.zdya.combatdocuments.exception.BusinessException;
import com.zdya.combatdocuments.mapper.*;
import com.zdya.combatdocuments.p2pNetwork.NodeUtil;
import com.zdya.combatdocuments.service.NetworkUserService;
import com.zdya.combatdocuments.service.SystemInfoService;
import com.zdya.combatdocuments.util.KillPortUtils;
import com.zdya.combatdocuments.util.ResultVoUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * * @author: bj
 * * @date: 2023/6/9
 * * @desc:
 */
@Slf4j
@Service
public class SystemInfoServiceImpl implements SystemInfoService {

    @Autowired
    private NetworkMapper networkMapper;
    @Autowired
    private NodeUtil nodeUtil;
    @Autowired
    private UserChatMapper userChatMapper;
    @Autowired
    private DocumentMapper documentMapper;
    @Autowired
    private DocumentApprovalMapper documentApprovalMapper;
    @Autowired
    private DocApprovalLimitMapper docApprovalLimitMapper;
    @Autowired
    private BroadcastMapper broadcastMapper;
    @Autowired
    private GradeMapper gradeMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private NetworkUserMapper networkUserMapper;

    /**
     * 清除聊天记录表、文书库表，文书审批记录表数据
     */
    @Override
    @Transactional
    public ResultVo clearData() {


        /**清楚聊天记录表&&图片+文档*/
        try {
            LambdaQueryWrapper<UserChat> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserChat::getNetId, nodeUtil.getNetworkId());
            List<UserChat> userChats = userChatMapper.selectList(wrapper);
            for (UserChat chat :userChats){
                String paths = "";
                //图片
                if(chat.getType() == 2){
                    String content = chat.getContent();
                    content = content.split("profile/")[1];
                    paths = CombatDocumentConfig.getProfile()+ File.separator+content;
                    try {
                        FileUtil.del(paths);
                    } catch (IORuntimeException e) {
                        e.printStackTrace();
                    }
                }
                //文件
                if(chat.getType() == 3){
                    String content = chat.getContent();
                    content = content.split("profile/")[1];
                    paths = CombatDocumentConfig.getProfile()+ File.separator+content;
                    try {
                        FileUtil.del(paths);
                    } catch (IORuntimeException e) {
                        e.printStackTrace();
                    }
                }
            }
            userChatMapper.delete(wrapper);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultVoUtil.error("清除数据失败");
        }

        // 清除文书库表
        try {
            LambdaQueryWrapper<Document> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Document::getNetId, nodeUtil.getNetworkId());
            //清除文书库本地文件
            List<Document> documents = documentMapper.selectList(wrapper);
            for (Document doc : documents){
                String path1 = doc.getPath();
                if(path1!=null){
                    try {
                        FileUtil.del(path1);
                    } catch (IORuntimeException e) {
                        e.printStackTrace();
                    }
                }
            }
            documentMapper.delete(wrapper);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultVoUtil.error("清除数据失败");
        }

        // 清除广播表
        try {
            LambdaQueryWrapper<Broadcast> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Broadcast::getNetId, nodeUtil.getNetworkId());
            broadcastMapper.delete(wrapper);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultVoUtil.error("清除数据失败");
        }

        // 清除网络表
        try {
            Long networkId = nodeUtil.getNetworkId();
            networkMapper.delete(new LambdaQueryWrapper<Network>().eq(Network::getId,networkId));
            networkUserMapper.delete(new LambdaQueryWrapper<NetworkUser>().eq(NetworkUser::getNetworkId,networkId));
            docApprovalLimitMapper.delete(new LambdaQueryWrapper<DocApprovalLimit>().eq(DocApprovalLimit::getNetworkId,networkId));
            gradeMapper.delete(new LambdaQueryWrapper<Grade>().eq(Grade::getNetworkId,networkId));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultVoUtil.error("清除数据失败");
        }

        // 清除聊天记录
        try{
            Network localNetwork = nodeUtil.getLocalNetwork();
            //关闭链服务
            KillPortUtils.start();
            //清除区块链文件夹
            String path = CombatDocumentConfig.getProfile() + File.separator + "ethereum" + File.separator+ localNetwork.getName() + "_" + localNetwork.getCreateName();

            FileUtil.del(path);
        }catch (Exception e){
            e.printStackTrace();
            return ResultVoUtil.error("清除数据失败");
        }

        return ResultVoUtil.success("清除数据成功");
    }

    /**
     * 查询文书限制设置信息
     * @return
     */
    @Override
    public List<DocApprovalLimit> queryDocLimit() {
        Long networkId = nodeUtil.getNetworkId();
        LambdaQueryWrapper<DocApprovalLimit> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocApprovalLimit::getNetworkId, networkId);
        return docApprovalLimitMapper.selectList(wrapper);
    }

    /**
     * 更新文书限制
     * @param docApprovalLimitVO
     * @return
     */
    @Override
    @Transactional
    public void updateDocLimit(DocApprovalLimitVO docApprovalLimitVO) {
        DocApprovalLimit docApprovalLimit = docApprovalLimitMapper.selectById(docApprovalLimitVO.getId());
        docApprovalLimit.setFirstLimittime(docApprovalLimitVO.getFirstLimittime());// 急
        docApprovalLimit.setSecondLimittime(docApprovalLimitVO.getSecondLimittime());// 加急
        docApprovalLimit.setThirdLimittime(docApprovalLimitVO.getThirdLimittime());// 特急
        docApprovalLimit.setUpdateTime(System.currentTimeMillis());
        try {
            docApprovalLimitMapper.updateById(docApprovalLimit);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BusinessException("更新失败！");
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type",9);
        jsonObject.put("docApprovalLimit",docApprovalLimit);
        nodeUtil.updateTableInfo(jsonObject.toString());

    }

    /**
     * 消息广播
     * @param broadcastVO
     */
    @Override
    @Transactional
    public void broadcast(BroadcastVO broadcastVO) {
        try {
            nodeUtil.broadcast(broadcastVO.getContent());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BusinessException("广播失败！");
        }
        Broadcast broadcast =  new Broadcast();
        broadcast.setNetId(nodeUtil.getNetworkId());
        broadcast.setContent(broadcastVO.getContent());
        broadcast.setUserId(broadcastVO.getUserId());
        broadcast.setCreateDate(System.currentTimeMillis());
        broadcastMapper.insert(broadcast);
    }

    /**
     * 查询所有广播记录
     * @return
     */
    @Override
    public ResultVo queryBroadcasts() {
//        List<Broadcast> all = broadcastMapper.findAll();
        LambdaQueryWrapper<Broadcast> wrapper = new LambdaQueryWrapper<>();
        wrapper.ne(Broadcast::getId,0);
        wrapper.eq(Broadcast::getNetId,nodeUtil.getNetworkId());
        wrapper.orderByDesc(Broadcast::getCreateDate);
        List<Broadcast> all = broadcastMapper.selectList(wrapper);

        List<JSONObject> list =new ArrayList<>();
        for(Broadcast broadcast: all){
            JSONObject jsonObject = new JSONObject();
            String sendName = userMapper.selectById(broadcast.getUserId()).getName();
            jsonObject.put("date",broadcast.getCreateDate());
            jsonObject.put("message",broadcast.getContent());
            jsonObject.put("sendName",sendName);
            list.add(jsonObject);
        }
        return ResultVoUtil.success(list);
    }

    /**
     * 查询当前网络阶段
     * @return
     */
    @Override
    public GradeVO queryNetGrade() {
        Long networkId = nodeUtil.getNetworkId();
        LambdaQueryWrapper<Grade> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Grade::getNetworkId, networkId);
        Grade grade = gradeMapper.selectOne(wrapper);
        GradeVO gradeVO = new GradeVO();
        gradeVO.setId(grade.getId());
        gradeVO.setGradeName(grade.getGradeName());
        gradeVO.setGradeTime(grade.getGradeTime());
        gradeVO.setNetworkId(grade.getNetworkId());
        gradeVO.setCreateUser(grade.getCreateUser());
        gradeVO.setCreateDate(grade.getCreateDate());
        return gradeVO;
    }

    /**
     * 更新当前网络阶段
     * @param
     * @return
     */
    @Override
    @Transactional
    public ResultVo updateNetGrade(GradeVO gradeVO) {
        List<Grade> gradeList = gradeVO.getGradeList();
        try{
            gradeMapper.delete(new QueryWrapper<Grade>().eq("network_id", nodeUtil.getNetworkId()));
            for(int i=0;i<gradeList.size();i++){
                gradeList.get(i).setId(null);
                gradeList.get(i).setNetworkId(nodeUtil.getNetworkId());
                gradeList.get(i).setCreateDate(System.currentTimeMillis());
                gradeMapper.insert(gradeList.get(i));
                Thread.sleep(3);
            }
            nodeUtil.setupGrade();
        }catch (Exception e){
            return ResultVoUtil.error("更新阶段失败");
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type",11);
        jsonObject.put("grades",gradeList);
        nodeUtil.updateTableInfo(jsonObject.toString());
        return ResultVoUtil.success();
    }
}
